/*
This codefile contains the functionality of the "HardwareOut" 
component. This component has not been specified in the design
report. This code manages a collection of countdown timers. 
They can be used to check when a given period of time has
passed. Running timers have a unique identifier (array index). 
Any number of timers can be used simultaneously, as long as 
they have a unique ID. There is no difference between a timer 
that has run out and a timer that has never been started.

The microcontroller's Timebase timer is used to generate
interrupts at a consistent interval. At each interrupt, every
running timer is counted down by the length of the interval.

Author:			Daan
Version: 		1
Last modified:	09-06-11
*/

// interface/facade implementation
void CountdownTimer_StartTimer (unsigned int timerId, float time)
{
	StartTimer(timerId, time);
}
BOOL CountdownTimer_HasTimerRunOutYet (unsigned int timerId)
{
	return HasTimerRunOutYet(timerId);
}



// global variables for this component
const float TIME_STEP = 0.1311f; // this is the interval in seconds, with which timers are updated
float timers[8];
unsigned int timerCount; // the number of currently usable timers (array size)



// initializing function for this component
void CountdownTimer_Initialize ()
{
	// initialize global variables
	unsigned int i;
	timerCount = 8;
	for (i=0; i<timerCount; i++)
	{
		timers[i] = 0.0f;
	}
	
	// configure the TimeBase timer's Interval Timer Function to an interval of 2^19/HCLK (Approx. 131.1ms).
	TBTC_RESV = ON; // manual says to set this bit. Okay..
	TBTC_TBIE = ON; // enable interrupt requests
	TBTC_TBOF = OFF; // clear the interrupt request flag bit
	TBTC_TBC = 0x3; // set the interval time
	TBTC_TBR = OFF; // clear the timer
	
	// initialize timebase's interrupt controller
	ICR12 &= 0xF8; // interrupt controller 12 (timebase timer): set interrupt level to 0 (highest)
}


/*
This is the function that is called on every interrupt.
*/
__interrupt void TimebaseTimer_isr (void)
{
	UpdateTimers();
	TBTC_TBOF = OFF;
}

/*
This routine runs every time the interval timer fires an interrupt. This counts down every timer with the set interval (TIME_STEP). If a timer has run out, it is reset.
*/
void UpdateTimers ()
{
	unsigned int i;
	
	for (i=0; i<timerCount; i++)
	{
		timers[i] -= TIME_STEP;
		
		if (timers[i] <= 0.0f)
		{
			timers[i] = 0.0f;
		}
	}
}

/*
Create a new countdown timer.
	timerId			A unique identifier for the timer, so that it can be looked up later.
	time			The length of time in seconds before it should run out.
*/
void StartTimer (unsigned int timerId, float time)
{
	timers[timerId] = time;
}

/*
check if a timer with the given 'id' still exists. If it doesn't exist, it means it has run out.
	timerId			The unique identifier for the timer.
*/
BOOL HasTimerRunOutYet (unsigned int timerId)
{
	if (timers[timerId] <= 0.0f)
	{
		return TRUE;
	}
	return FALSE;
}